
# coding:utf-8

from lib import flux, pymunk
from lib.fluxext import ViewGroup
from system.map import MapManager
from scripts.base import config
from utils import dir2vec
from system import phy


class Bullet(ViewGroup):
    BulletOne = {}

    def GetMapPos(self):
        p = self.v.GetPos()
        return [p.x/ config.TILESIZE, p.y/ config.TILESIZE]

    def SetMapPos(self, x, y):
        self.v.SetPos(x* config.TILESIZE, y* config.TILESIZE)

    def __init__(self, cls, r=1, lifetime=0.5):
        self.r = r
        self.dmg = 3.5
        self.v = cls()
        super(Bullet, self).__init__()
        self.v.SetAnchor(MapManager().map_top_left)
        self.v.OnMessage = self.OnMessage
        self.BulletOne[self] = 1
        self.t = flux.Timeout(lifetime)

    def SetPos(self, x, y):
        self.v.SetPos(x, y)

    def SetMove(self, x, y, time=1):
        self.v.Anim().Move(time, flux.utils.Vec2f(x, y), 'bullet') #.SetPause(True)
        self.v.Anim().Do()

    def SetMapMove(self, x, y, time=1):
        self.SetMove(x* config.TILESIZE, y* config.TILESIZE, time)

    def ApplyPhy(self):
        pos = self.v.GetPos()
        size = self.v.GetSize()
        body = pymunk.Body(1, pymunk.moment_for_circle(1, self.r, self.r))
        body.position = pymunk.vec2d.Vec2d(pos.x, pos.y)
        body.velocity_limit = 1000

        poly = pymunk.Circle(body, self.r)
        phy.space.add(body, poly)

        self.body = body
        phy.Reg(body, self)

    def Shoot(self, _dir):
        pos = self.v.GetPos()
        x, y = dir2vec(_dir, 25)
        self.v.SetPos(pos.x+x, pos.y+y)

        self.ApplyPhy()
        x, y = dir2vec(_dir, 400)
        self.body.velocity = x, y

    def _del(self):
        del self.v
        self.v = None
        del self.t
        self.t = None
        del self.BulletOne[self]


    def OnMessage(self, msg):
        self.OnOver()
        del self.v
        self.v = None
        del self.BulletOne[self]

    def OnOver(self):
        pass

    def SetAngle(self, angle):
        self.v.SetAngle(angle)

# 标准子弹
class StdBullet(Bullet):

    def __init__(self, r=0.1):
        super(StdBullet, self).__init__(flux.View)
        self.v.SetSize(4,4)
        self.v.SetColor(0,0,1)


# 玩家子弹
class PlayerBullet(Bullet):

    def __init__(self, r=0.1):
        super(PlayerBullet, self).__init__(flux.View)
        self.v.SetSize(4,4)
        self.v.SetColor(0,0,1)
        self.dmg = 2

    def ApplyPhy(self):
        pos = self.v.GetPos()
        size = self.v.GetSize()
        body = pymunk.Body(1, pymunk.moment_for_circle(1, self.r, self.r))
        body.position = pymunk.vec2d.Vec2d(pos.x, pos.y)
        body.velocity_limit = 1000

        poly = pymunk.Circle(body, self.r)
        poly.group = phy.GROUP_PLAYER_BULLET
        poly.layers = pow(2, 3)
        phy.space.add(body, poly)

        self.body = body
        phy.Reg(body, self)

    def Shoot(self, _dir):
        pos = self.v.GetPos()
        x, y = dir2vec(_dir, 25)
        self.v.SetPos(pos.x+x, pos.y+y)

        self.ApplyPhy()
        x, y = dir2vec(_dir, 300)
        self.body.velocity = x, y

        def a():
            phy.Remove(self.body)
            self._del()
        self.t.OnFire = a
        self.t.Start()


# 敌人子弹
class EnemyBullet(Bullet):

    def __init__(self, r=0.1):
        super(EnemyBullet, self).__init__(flux.View)
        self.v.SetSize(8,8)
        self.v.SetColor(1,0,0)

    def ApplyPhy(self):
        pos = self.v.GetPos()
        size = self.v.GetSize()
        body = pymunk.Body(1, pymunk.moment_for_circle(1, self.r, self.r))
        body.position = pymunk.vec2d.Vec2d(pos.x, pos.y)
        body.velocity_limit = 1000

        poly = pymunk.Circle(body, self.r)
        poly.group = phy.GROUP_ENEMY_BULLET
        poly.layers = pow(2, 1)
        phy.space.add(body, poly)

        self.body = body
        phy.Reg(body, self)

    def Shoot(self, _dir):
        pos = self.v.GetPos()
        x, y = dir2vec(_dir, 25)
        self.v.SetPos(pos.x+x, pos.y+y)

        self.ApplyPhy()
        x, y = dir2vec(_dir, 300)
        self.body.velocity = x, y

        def a():
            phy.Remove(self.body)
            self._del()
        self.t.OnFire = a
        self.t.Start()
